﻿using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NPOI.SS.Formula.Functions;

namespace FreeDream.Common.Helper
{
    public static class ImageHelper
    {
        private static string ClassName = "ImageHelper";

        /// <summary>
        /// Image转byte[]
        /// </summary>
        /// <param name="image"></param>
        /// <returns></returns>
        public static byte[] ImageToBytes(Image image)
        {
            ImageFormat format = image.RawFormat;
            using (MemoryStream ms = new MemoryStream())
            {
                image.Save(ms, ImageFormat.Png);
                byte[] buffer = new byte[ms.Length];
                //Image.Save()会改变MemoryStream的Position，需要重新Seek到Begin
                ms.Seek(0, SeekOrigin.Begin);
                ms.Read(buffer, 0, buffer.Length);
                return buffer;
            }
        }
        public static byte[] JpegImageToBytes(Image image)
        {
            ImageFormat format = image.RawFormat;
            using (MemoryStream ms = new MemoryStream())
            {
                image.Save(ms, ImageFormat.Jpeg);
                byte[] buffer = new byte[ms.Length];
                //Image.Save()会改变MemoryStream的Position，需要重新Seek到Begin
                ms.Seek(0, SeekOrigin.Begin);
                ms.Read(buffer, 0, buffer.Length);
                return buffer;
            }
        }

        #region 1.1 jpeg 和png 转base64

        /// <summary>
        /// JpegImage转Base64字符串
        /// </summary>
        /// <param name="image"></param>
        /// <returns></returns>
        public static string ImageToJpegBase64String(Image image)
        {
            if (image == null)
            {
                return "";
            }
            return Convert.ToBase64String(JpegImageToBytes(image));
        }
        /// <summary>
        /// pngImage转Base64字符串
        /// </summary>
        /// <param name="image"></param>
        /// <returns></returns>
        public static string ImageToBase64String(Image image)
        {
            return Convert.ToBase64String(ImageToBytes(image));
        }

        #endregion

        #region 1.2 Bitmap和Base64String互转

        /// <summary>
        /// bitmap 转base64
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns></returns>
        public static string BitmapToBase64String(Bitmap bitmap)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                bitmap.Save(ms, ImageFormat.Png);
                byte[] buffer = new byte[ms.Length];
                //Image.Save()会改变MemoryStream的Position，需要重新Seek到Begin
                ms.Seek(0, SeekOrigin.Begin);
                ms.Read(buffer, 0, buffer.Length);
                //ms.Position = 0;
                //ms.Read(arr, 0, (int)ms.Length);
                //ms.Close();
                return Convert.ToBase64String(buffer);
            }
        }

        /// <summary>
        /// Base64转Bitmap
        /// </summary>
        /// <param name="inputStr"></param>
        /// <returns></returns>
        public static Bitmap Base64StringToBitmap(string inputStr)
        {
            try
            {
                byte[] arr = Convert.FromBase64String(inputStr);
                using (MemoryStream ms = new MemoryStream(arr))
                {
                    Bitmap bmp = new Bitmap(ms);
                    return bmp;
                }
            }
            catch
            {
                return null;
            }
        }
        #endregion

        #region 2.1 Base64字符串转Image

        /// <summary>
        /// Base64字符串转Image
        /// </summary>
        /// <param name="base64"></param>
        /// <returns></returns>
        public static Image Base64StringToImage(string base64)
        {
            string newSubstring = base64.Trim().Substring(base64.IndexOf(",") + 1);
            byte[] buffer = Convert.FromBase64String(newSubstring);
            return BytesToImage(buffer);
        }
        #endregion

        #region 3.1 保存Jpeg，png图片到指定路径

        /// <summary>
        /// 保存Jpeg图片到指定路径
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="base64sstr"></param>
        /// <param name="path"></param>
        /// <returns></returns>
        public static bool SaveImageInFloder(string filename, string base64sstr, string path)
        {
            return SaveImg(filename, base64sstr, path, "jpeg");
            //try
            //{
            //    string imgpath = AppDomain.CurrentDomain.BaseDirectory + "/" + path;
            //    if (!Directory.Exists(imgpath))
            //    {
            //        Directory.CreateDirectory(imgpath);
            //    }
            //    string fileloacat = string.Format(@"{0}\{1}.jpg", imgpath, filename);
            //    using (var myImage = Base64StringToImage(base64sstr))
            //    {
            //        if (File.Exists(fileloacat))
            //        {
            //            File.Delete(fileloacat);
            //        }
            //        myImage.Save(fileloacat, ImageFormat.Jpeg);
            //        return true;
            //    }
            //}
            //catch (Exception ex)
            //{
            //    QueenLogger.Error(filename + ",保存失败," + ex.Message, ClassName, ex);
            //    return false;
            //}
        }
        /// <summary>
        /// 保存Jpeg图片到指定路径
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="base64sstr"></param>
        /// <param name="path"></param>
        /// <param name="imgType">bmp,emf,wmf,gif,jpeg,png,tiff,exif,icon</param>
        /// <returns></returns>
        public static bool SaveImg(string filename, string base64sstr, string path, string imgType)
        {
            try
            {
                string imgpath = AppDomain.CurrentDomain.BaseDirectory + "/" + path;
                if (!Directory.Exists(imgpath))
                {
                    Directory.CreateDirectory(imgpath);
                }
                string fileloacat = $@"{imgpath}\{filename}.{imgType}";
                using (var myImage = Base64StringToImage(base64sstr))
                {
                    if (File.Exists(fileloacat))
                    {
                        File.Delete(fileloacat);
                    }
                    myImage.Save(fileloacat, GetImageFormat(imgType));
                    return true;
                }
            }
            catch (Exception ex)
            {
                QueenLogger.Error(filename + ",保存失败," + ex.Message, ClassName, ex);
                return false;
            }
        }
        /// <summary>
        /// bmp,emf,wmf,gif,jpeg,png,tiff,exif,icon
        /// </summary>
        /// <param name="ImageType">bmp,emf,wmf,gif,jpeg,png,tiff,exif,icon</param>
        /// <returns></returns>
        private static ImageFormat GetImageFormat(string ImageType)
        {
            switch (ImageType)
            {
                case "bmp":
                    return ImageFormat.Bmp;
                case "emf":
                    return ImageFormat.Emf;
                case "wmf":
                    return ImageFormat.Wmf;
                case "gif":
                    return ImageFormat.Gif;
                case "png":
                    return ImageFormat.Png;
                case "tiff":
                    return ImageFormat.Tiff;
                case "exif":
                    return ImageFormat.Exif;
                case "icon":
                    return ImageFormat.Icon;
                case "jpeg":
                default:
                    return ImageFormat.Jpeg;

            }
        }

        /// <summary>
        /// 保存Png图片到指定路径
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="base64sstr"></param>
        /// <param name="path"></param>
        /// <returns></returns>
        public static bool SavePngInFloder(string filename, string base64sstr, string path)
        {
            return SaveImg(filename, base64sstr, path, "png");
            //try
            //{
            //    string imgpath = AppDomain.CurrentDomain.BaseDirectory + "/" + path;
            //    if (!Directory.Exists(imgpath))
            //    {
            //        Directory.CreateDirectory(imgpath);
            //    }
            //    string fileloacat = string.Format(@"{0}\{1}.png", imgpath, filename);
            //    using (var myImage = Base64StringToImage(base64sstr))
            //    {
            //        if (File.Exists(fileloacat))
            //        {
            //            File.Delete(fileloacat);
            //        }
            //        myImage.Save(fileloacat, ImageFormat.Png);
            //        return true;
            //    }
            //}
            //catch (Exception ex)
            //{
            //    QueenLogger.Error(filename + ",保存失败," + ex.Message, ClassName, ex);
            //    return false;
            //}
        }

        #endregion

        /// <summary>
        /// Byte[]转Image
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public static Image BytesToImage(byte[] buffer)
        {
            MemoryStream ms = new MemoryStream(buffer);
            Image image = Image.FromStream(ms);
            //image.RotateFlip(RotateFlipType.Rotate180FlipNone);   //旋转
            return image;
        }


        /// <summary>
        /// 图片转为base64编码的字符串
        /// </summary>
        /// <param name="Imagefilename"></param>
        /// <returns></returns>
        public static string ImgToBase64String(string Imagefilename)
        {
            try
            {
                Bitmap bmp = new Bitmap(Imagefilename);
                MemoryStream ms = new MemoryStream();
                bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                byte[] arr = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(arr, 0, (int)ms.Length);
                ms.Close();
                return Convert.ToBase64String(arr);
            }
            catch (Exception ex)
            {
                QueenLogger.Error(ex.Message, ClassName, ex);
                return null;
            }
        }

        #region 6.0 图片处理，图片压缩

        /// <summary>
        /// 图像缩略图处理
        /// </summary>
        /// <param name="bytes">图像源数据</param>
        /// <param name="compression">压缩质量 1-100</param>
        /// <param name="thumbWidth">缩略图的宽</param>
        /// <param name="thumbHeight">缩略图的高</param>
        /// <returns></returns>
        public static byte[] ConvertToThumbnail(byte[] bytes, int compression = 100, int thumbWidth = 0, int thumbHeight = 0)
        {
            byte[] bs = null;

            try
            {
                if (bytes != null)
                {
                    using (MemoryStream ms = new MemoryStream(bytes))
                    {
                        using (Bitmap srcimg = new Bitmap(ms))
                        {
                            if (thumbWidth == 0 && thumbHeight == 0)
                            {
                                thumbWidth = srcimg.Width;
                                thumbHeight = srcimg.Height;
                            }
                            using (Bitmap dstimg = new Bitmap(thumbWidth, thumbHeight))//图片压缩质量
                            {
                                //从Bitmap创建一个System.Drawing.Graphics对象，用来绘制高质量的缩小图。
                                using (Graphics gr = Graphics.FromImage(dstimg))
                                {
                                    //把原始图像绘制成上面所设置宽高的缩小图
                                    Rectangle rectDestination = new Rectangle(0, 0, thumbWidth, thumbHeight);
                                    gr.Clear(Color.WhiteSmoke);
                                    gr.CompositingQuality = CompositingQuality.HighQuality;
                                    gr.SmoothingMode = SmoothingMode.HighQuality;
                                    gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
                                    gr.DrawImage(srcimg, rectDestination, 0, 0, srcimg.Width, srcimg.Height, GraphicsUnit.Pixel);

                                    EncoderParameters ep = new EncoderParameters(1);
                                    ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, compression);//设置压缩的比例1-100
                                    ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
                                    ImageCodecInfo jpegICIinfo = arrayICI.FirstOrDefault(t => t.FormatID == System.Drawing.Imaging.ImageFormat.Jpeg.Guid);
                                    using (MemoryStream dstms = new MemoryStream())
                                    {
                                        if (jpegICIinfo != null)
                                        {
                                            dstimg.Save(dstms, jpegICIinfo, ep);
                                        }
                                        else
                                        {
                                            dstimg.Save(dstms, System.Drawing.Imaging.ImageFormat.Jpeg);//保存到内存里
                                        }
                                        bs = new Byte[dstms.Length];
                                        dstms.Position = 0;
                                        dstms.Read(bs, 0, bs.Length);

                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch
            {
                return null;
            }
            return bs;
        }

        public static byte[] Base64StringToBytes(string base64str)
        {
            return Convert.FromBase64String(base64str);
        }

        public static string BytesToBase64String(byte[] bytes)
        {
            return Convert.ToBase64String(bytes);
        }
        /// <summary>
        /// base64图片压缩
        /// </summary>
        /// <param name="base64String"></param>
        /// <param name="compression"></param>
        /// <returns></returns>
        public static string ConvertToThumbnail(string base64String, out int size, int compression = 100)
        {
            size = 0;
            try
            {
                var zipBytes = ImageHelper.Base64StringToBytes(base64String);
                byte[] newBytes = ImageHelper.ConvertToThumbnail(zipBytes, compression);
                size = newBytes.Length;
                var temp64 = ImageHelper.BytesToBase64String(newBytes);
                return temp64;
            }
            catch
            {
                // ignored
            }
            return base64String;
        }
        /// <summary>
        /// 自动压缩图片大小
        /// </summary>
        /// <param name="base64String"></param>
        /// <param name="size"></param>
        /// <param name="minKb"></param>
        /// <param name="maxKb"></param>
        /// <param name="compression"></param>
        /// <returns></returns>
        public static string ConvertToThumbnail(string base64String, out int size, int minKb, int maxKb, int compression = 100)
        {
            size = 0;
            try
            {
                var zipBytes = ImageHelper.Base64StringToBytes(base64String);
                var temp64 = ConvertToThumbnail(zipBytes, out size, compression, minKb, maxKb);
                return temp64;
            }
            catch
            {
                // ignored
            }
            return base64String;
        }

        /// <summary>
        /// 自动压缩图片大小
        /// </summary>
        /// <param name="zipBytes"></param>
        /// <param name="size"></param>
        /// <param name="compression"></param>
        /// <param name="minKb">单位Kb</param>
        /// <param name="maxKb">单位Kb</param>
        /// <returns></returns>
        public static string ConvertToThumbnail(byte[] zipBytes, out int size, int compression, int minKb, int maxKb)
        {
            size = 0;
            try
            {
                byte[] newBytes = ImageHelper.ConvertToThumbnail(zipBytes, compression);
                size = newBytes.Length;
                var kbSize = size / 1024;
                if (kbSize < minKb)
                {
                    ConvertToThumbnail(zipBytes, out size, ++compression, minKb, maxKb);
                }
                else if (kbSize > maxKb)
                {
                    ConvertToThumbnail(zipBytes, out size, --compression, minKb, maxKb);
                }
                var temp64 = ImageHelper.BytesToBase64String(newBytes);
                return temp64;
            }
            catch
            {
                // ignored
            }
            return "";
        }

        #endregion

        #region 6.1 图片合并
        public static string MegerBase64Imgs(string[] base64Strs)
        {
            //最大宽度和高度
            int maL = 0, totalH = 0;

            //循环遍历获取文件的最大宽度与总高度
            for (int i = 0; i < base64Strs.Length; i++)
            {
                Image image = Image.FromStream(new System.IO.MemoryStream(Convert.FromBase64String(base64Strs[i])));
                if (image.Width > maL) maL = image.Width;
                totalH = totalH + image.Height + 5;
            }
            if (totalH == 0 || maL == 0) return "";

            Bitmap map = new Bitmap(maL, totalH);//定义画布
            Graphics g = Graphics.FromImage(map);//定义画笔
            g.Clear(Color.White);//把画布更改为白色
            int y = 0;//y轴坐标
            for (int i = 0; i < base64Strs.Length; i++)
            {
                Image image = Image.FromStream(new System.IO.MemoryStream(Convert.FromBase64String(base64Strs[i])));
                g.DrawImage(image, 0, y, image.Width, image.Height);
                y = y + image.Height + 5;//y的告诉 5是为了让画布有个缝隙
            }
            g.Dispose();
            return null;
        }
        #endregion

        #region 6.3 图片去掉白色背景 png
        public static Bitmap BitmapRemoveBackground(Bitmap bitmap)
        {
            var replaceBc = Color.FromArgb(255, 255, 255);
            var tolerance = 30;
            for (int i = bitmap.Size.Width - 1; i >= 0; i--)
            {
                for (int j = bitmap.Size.Height - 1; j >= 0; j--)
                {
                    var col = bitmap.GetPixel(i, j);
                    if (255 - col.R < tolerance && 255 - col.G < tolerance && 255 - col.B < tolerance)
                    {
                        bitmap.SetPixel(i, j, replaceBc);
                    }
                }
            }
            bitmap.MakeTransparent(replaceBc);
            return bitmap;
        }

        #endregion

        /// <summary>
        /// 将图片旋转到正确位置
        /// 旋转角度  参数值
        /// 0°	        1
        /// 顺时针90°	6
        /// 逆时针90°	8
        /// 180°	    3
        /// </summary>
        /// <param name="image">图片对象</param>
        /// <returns></returns>
        public static void OrientationImage(Image image)
        {
            if (Array.IndexOf(image.PropertyIdList, 274) <= -1) return;
            var orientation = (int)image.GetPropertyItem(274).Value[0];
            switch (orientation)
            {
                case 1:
                    // No rotation required.
                    break;
                case 2:
                    image.RotateFlip(RotateFlipType.RotateNoneFlipX);
                    break;
                case 3:
                    image.RotateFlip(RotateFlipType.Rotate180FlipNone);
                    break;
                case 4:
                    image.RotateFlip(RotateFlipType.Rotate180FlipX);
                    break;
                case 5:
                    image.RotateFlip(RotateFlipType.Rotate90FlipX);
                    break;
                case 6:
                    image.RotateFlip(RotateFlipType.Rotate90FlipNone);
                    break;
                case 7:
                    image.RotateFlip(RotateFlipType.Rotate270FlipX);
                    break;
                case 8:
                    image.RotateFlip(RotateFlipType.Rotate270FlipNone);
                    break;
            }
            image.RemovePropertyItem(274);
        }

        /// <summary>
        /// 旋转180°，并镜像
        /// </summary>
        /// <param name="image"></param>
        public static void OrientationImage_Rotate180FlipX(ref Image image)
        {
            image.RotateFlip(RotateFlipType.Rotate180FlipX);
        }


        #region 图片转换--注释

        ///// <summary>
        ///// Base64String → Image
        ///// </summary>
        ///// <param name="pictureBase64"></param>
        ///// <param name="rotateFlipType"></param>
        ///// <returns></returns>
        //public static Image String2Image(string pictureBase64, RotateFlipType rotateFlipType = RotateFlipType.Rotate180FlipNone)
        //{
        //    //var json = JsonConvert.DeserializeObject<SaveImageRepDataQueueModel>(obj as string);
        //    //string pictureName = json.PictureName;
        //    //string pictureBase64 = json.PictureBase64;

        //    ////没有对象，proterties获取异常
        //    ////var proterties = obj.GetType().GetProperties().ToList();
        //    ////if (!proterties.Exists(p => p.Name.Equals("PictureName", StringComparison.OrdinalIgnoreCase)) ||
        //    ////    !proterties.Exists(p => p.Name.Equals("PictureBase64", StringComparison.OrdinalIgnoreCase)))
        //    ////{
        //    ////    return new ResultParam { code = 1, message = "参数缺失" };
        //    ////}
        //    ////string pictureName = obj.GetType().GetProperty("PictureName").GetValue(obj).ToString();
        //    ////string pictureBase64 = obj.GetType().GetProperty("PictureBase64").GetValue(obj).ToString();

        //    try
        //    {
        //        //logger.Debug("SaveImage Start.");
        //        pictureBase64 = pictureBase64.Replace("data:image/png;base64,", "").Replace("data:image/jgp;base64,", "").Replace("data:image/jpg;base64,", "").Replace("data:image/jpeg;base64,", "").Replace("data:image/jpng;base64,", "");//将base64头部信息替换
        //        byte[] bytes = Convert.FromBase64String(pictureBase64);
        //        MemoryStream memStream = new MemoryStream(bytes);
        //        Image mImage = Image.FromStream(memStream);
        //        mImage.RotateFlip(rotateFlipType);
        //        return mImage;
        //        //Bitmap bp = new Bitmap(mImage);
        //        ////string path = @"E:\images";
        //        //string path = Environment.CurrentDirectory + "\\images";//@"E:\images";
        //        //if (!Directory.Exists(path))
        //        //{
        //        //    Directory.CreateDirectory(path);
        //        //}
        //        //DateTime now = DateTime.Now;
        //        //string fileName = pictureName;
        //        //if (fileName == string.Empty)
        //        //    fileName = now.ToString("yyyy-MM-dd-HH-mm-ffff");
        //        //string filePath = path + "\\" + fileName + ".jpg";
        //        //bp.Save(filePath);
        //        //logger.Debug("SaveImage End.");
        //    }
        //    catch (Exception ex)
        //    {
        //        return null;
        //        //return new ResultParam() { code = 9999, message = $"base64转图片失败，错误详情:  {ex.Message}", data = null };
        //        //LogerHelper.CreateLogTxt($"Return base64转图片失败，错误详情:  {ex.Message}");
        //        //throw;
        //    }

        //}
        ///// <summary>
        ///// Image → Base64String
        ///// </summary>
        ///// <param name="img"></param>
        ///// <returns></returns>
        //public static string Image2Base64(Image img)
        //{
        //    try
        //    {
        //        Bitmap bmp = new Bitmap(img);
        //        MemoryStream ms = new MemoryStream();
        //        bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
        //        byte[] arr = new byte[ms.Length];
        //        ms.Position = 0;
        //        ms.Read(arr, 0, (int)ms.Length);
        //        ms.Close();
        //        return Convert.ToBase64String(arr);
        //    }
        //    catch (Exception ex)
        //    {
        //        return null;
        //    }
        //}

        ///// <summary>
        ///// Base64转Bitmap
        ///// </summary>
        ///// <param name="inputStr"></param>
        ///// <returns></returns>
        //public static Bitmap Base64StringToBitmap(string inputStr)
        //{
        //    try
        //    {
        //        byte[] arr = Convert.FromBase64String(inputStr);
        //        MemoryStream ms = new MemoryStream(arr);
        //        Bitmap bmp = new Bitmap(ms);
        //        ms.Close();
        //        return bmp;
        //    }
        //    catch (Exception ex)
        //    {
        //        Console.WriteLine(ex.Message.ToString());
        //        return null;
        //    }
        //}

        ///// <summary>
        ///// Bitmap转Base64
        ///// </summary>
        ///// <param name="bmp"></param>
        ///// <returns></returns>
        //public static string BitmapToBase64(Bitmap bmp)
        //{
        //    try
        //    {
        //        MemoryStream ms = new MemoryStream();
        //        bmp.Save(ms, ImageFormat.Jpeg);
        //        byte[] arr = new byte[ms.Length];
        //        ms.Position = 0;
        //        ms.Read(arr, 0, (int)ms.Length);
        //        ms.Close();
        //        String strbaser64 = Convert.ToBase64String(arr);
        //        return strbaser64;
        //    }
        //    catch (Exception ex)
        //    {
        //        return "";
        //    }
        //}

        #endregion
    }
    /// <summary>
    /// bmp,emf,wmf,gif,jpeg,png,tiff,exif,icon
    /// </summary>
    public class ImageType
    {
        public static string MemoryBmp => "memoryBMP";

        public static string Bmp => "bmp";

        public static string Emf => "emf";

        public static string Wmf => "wmf";

        public static string Gif => "gif";

        public static string Jpeg => "jpeg";

        public static string Png => "png";

        public static string Tiff => "tiff";

        public static string Exif => "exif";

        public static string Icon => "icon";
    }

    
}
